package com.mspbots.rule.queue.producer;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mspbots.api.service.MessagesService;
import com.mspbots.api.service.TenantRuleService;
import com.mspbots.api.service.TenantService;
import com.mspbots.cw.request.EscalationDTO;
import com.mspbots.cw.request.TenantDTO;
import com.mspbots.cw.request.TenantRuleDTO;
import com.mspbots.cw.request.TriggerEscalationDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.mspbots.rule.config.RuleConfiguration.REDIS_KEY_PREFIX_TENANT;

/**
 * @author Dennis
 */
@Slf4j
@Component
public class TriggerEscalationProducer {

    @Autowired
    MessagesService messagesService;
    @Autowired
    TenantService tenantService;
    @Autowired
    TenantRuleService tenantRuleService;
    @Autowired
    private RabbitMessagingTemplate messagingTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ObjectMapper objectMapper;

    @Scheduled(cron = "0 0/1 * * * *")
    public void produce() {
        List<TenantDTO> tenantDTOS = objectMapper.convertValue(redisTemplate.opsForList().range(REDIS_KEY_PREFIX_TENANT + "tenants", 0, -1), new TypeReference<List<TenantDTO>>() {
        });

        List<TenantDTO> tenantsActive = tenantDTOS.stream().filter(item -> item.getStatusId() == 1).collect(Collectors.toList());
        for (TenantDTO tenantDTO : tenantsActive) {
            Map<String, Object> tenantsParams = Map.of("tenantId", tenantDTO.getId(),
                    "escalation", 1);

            List<TenantRuleDTO> tenantRuleDTOList = tenantRuleService.getEscalation(tenantsParams);
            for (TenantRuleDTO tenantRuleDTO : tenantRuleDTOList) {
                Map<String, Object> param = Map.of("tenantId", tenantRuleDTO.getTenantId(), "ruleId", tenantRuleDTO.getRuleId(), "name", tenantRuleDTO.getName());
                List<EscalationDTO> escalationDTOList = tenantRuleService.selectEscalationParams(param);
                for (int i = 0; i < escalationDTOList.size(); i++) {
                    Base64.Encoder encoder = Base64.getEncoder();
                    String template = encoder.encodeToString(escalationDTOList.get(i).getTemplate().getBytes());
                    Map<String, Object> params = new HashMap<>();
                    if (escalationDTOList.size() > i + 1) {
                        params = Map.of("times", escalationDTOList.get(i).getTimes(), "nextimes", escalationDTOList.get(i + 1).getTimes(), "tenantId", escalationDTOList.get(i).getTenantId(),
                                "ruleId", escalationDTOList.get(i).getRuleId(), "name", escalationDTOList.get(i).getName(), "level", escalationDTOList.get(i).getLevel(),
                                "template", template);
                    } else {
                        params = Map.of("times", escalationDTOList.get(i).getTimes(), "tenantId", escalationDTOList.get(i).getTenantId(),
                                "ruleId", escalationDTOList.get(i).getRuleId(), "name", escalationDTOList.get(i).getName(), "level", escalationDTOList.get(i).getLevel(),
                                "template", template);
                    }
                    List<TriggerEscalationDTO> triggerEscalationDTOList = messagesService.triggerEscalationList(params);
                    if (!CollectionUtils.isEmpty(triggerEscalationDTOList)) {
                        if (i == 0) {
                            this.messagingTemplate.convertAndSend("msp.rule.topic", "trigger.escalationUser.#", triggerEscalationDTOList);
                        } else {
                            this.messagingTemplate.convertAndSend("msp.rule.topic", "trigger.escalationManager.#", triggerEscalationDTOList);
                        }
                    }
                }
            }
        }
    }
}
